package com.beidasoft.web.util.fileUtil;

import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.StrUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @Author zhangwj1
 * @Description TODO
 * @date 2022/10/13 14:32
 * @Version 1.0
 */

public class FileDownloadUtils {
    private static Logger logger = LoggerFactory.getLogger(FileDownloadUtils.class);
    private static final String fileFlg = "__";

    public FileDownloadUtils() {
    }

    public static void downloadFile(HttpServletRequest request, String path, HttpServletResponse response) throws IOException {
        downloadFile((String)path, (String)null, request, response);
    }

    public static void downloadFile(String path, String fileName, HttpServletRequest request, HttpServletResponse response) throws IOException {
        InputStream fis = null;

        try {
            File file = new File(path);
            if (StrUtil.isBlank(fileName)) {
                fileName = file.getName();
            }

            if (fileName.contains("__")) {
                fileName = fileName.substring(fileName.lastIndexOf("__") + 1);
            }

            String extName = FileNameUtil.extName(path);
            if (StrUtil.isNotBlank(extName) && !fileName.endsWith(extName)) {
                fileName = fileName + "." + extName;
            }

            fis = new FileInputStream(path);
            downloadFile((InputStream)fis, fileName, request, response);
        } catch (IOException var10) {
            logger.error("发生了异常异常信息为：", var10);
            logger.error(">>文件路径:{}>>>", path);
            throw new IOException("文件路径错误，下载文件失败");
        } finally {
            if (fis != null) {
                fis.close();
            }

        }

    }

    public static void downloadFile(InputStream inputStream, String fileName, HttpServletRequest request, HttpServletResponse response) throws IOException {
        OutputStream outputStream = null;

        try {
            String userAgent = request.getHeader("User-Agent");
            fileName = getFileDownName(fileName, userAgent);
            response.reset();
            response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
            response.setContentType("application/octet-stream");
            outputStream = response.getOutputStream();
            copyStream(inputStream, outputStream);
        } catch (IOException var9) {
            logger.error("发生了异常异常信息为：", var9);
            throw new IOException("文件路径错误，下载文件失败");
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }

            if (outputStream != null) {
                outputStream.close();
            }

        }

    }

    public static String getFileDownName(String fileName, String userAgent) throws UnsupportedEncodingException {
        if (userAgent.toLowerCase().indexOf("msie") <= 0 && userAgent.indexOf("like Gecko") <= 0) {
            fileName = new String(fileName.replaceAll(" ", "").getBytes(StandardCharsets.UTF_8), "ISO8859-1");
        } else {
            fileName = URLEncoder.encode(fileName, "UTF-8");
        }

        return fileName;
    }

    public static void copyStream(InputStream is, OutputStream os) throws IOException {

        try {
            ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
            byte[] buff = new byte[100];

            int rc;
            while((rc = is.read(buff, 0, 100)) > 0) {
                swapStream.write(buff, 0, rc);
            }

            byte[] data = swapStream.toByteArray();
            os.write(data);
            os.close();
        } catch (IOException var9) {
            logger.error("文件转化错误", var9);
        } finally {
            is.close();
        }

    }

    public static boolean DirectoryExists(String path) {
        File file = new File(path);
        return file.exists() || file.isDirectory();
    }

    public static boolean createDir(String destDirName) {
        File dir = new File(destDirName);
        if (dir.exists()) {
            return false;
        } else {
            if (!destDirName.endsWith(File.separator)) {
                destDirName = destDirName + File.separator;
            }

            return dir.mkdirs();
        }
    }

    public static boolean FileExists(String path) {
        File file = new File(path);
        return file.exists() || file.isFile();
    }

    public static void zipd(String zipTmp, List<File> files, HttpServletRequest request, HttpServletResponse response) {
        File zipTmpFile = new File(zipTmp);

        try {
            if (zipTmpFile.exists()) {
                zipTmpFile.delete();
            }

            zipTmpFile.createNewFile();
            response.reset();
            FileOutputStream fous = new FileOutputStream(zipTmpFile);
            ZipOutputStream zipOut = new ZipOutputStream(fous);
            zipFile(files, zipOut);
            zipOut.close();
            fous.close();
            downloadZip(zipTmpFile, request, response);
        } catch (IOException var7) {
            logger.error("发生了异常异常信息为：", var7);
        }

    }

    public static void zipFile(List files, ZipOutputStream outputStream) {
        int size = files.size();

        for(int i = 0; i < size; ++i) {
            File file = (File)files.get(i);
            zipFile(file, outputStream);
        }

    }

    public static void zipFile(File inputFile, ZipOutputStream ouputStream) {
        try {
            if (inputFile.exists()) {
                if (inputFile.isFile()) {
                    FileInputStream IN = new FileInputStream(inputFile);
                    BufferedInputStream bins = new BufferedInputStream(IN, 512);
                    ZipEntry entry = new ZipEntry(inputFile.getName());
                    ouputStream.putNextEntry(entry);
                    byte[] buffer = new byte[512];

                    int nNumber;
                    while((nNumber = bins.read(buffer)) != -1) {
                        ouputStream.write(buffer, 0, nNumber);
                    }

                    bins.close();
                    IN.close();
                } else {
                    try {
                        File[] files = inputFile.listFiles();

                        for(int i = 0; i < files.length; ++i) {
                            zipFile(files[i], ouputStream);
                        }
                    } catch (Exception var7) {
                        logger.error("发生了异常异常信息为：", var7);
                    }
                }
            }
        } catch (Exception var8) {
            logger.error("发生了异常异常信息为：", var8);
        }

    }

    public static HttpServletResponse downloadZip(File file, HttpServletRequest request, HttpServletResponse response) {
        if (!file.exists()) {
            System.out.println("待压缩的文件目录：" + file + "不存在.");
        } else {
            boolean var15 = false;

            File f;
            label79: {
                try {
                    var15 = true;
                    InputStream fis = new BufferedInputStream(new FileInputStream(file.getPath()));
                    byte[] buffer = new byte[fis.available()];
                    fis.read(buffer);
                    fis.close();
                    response.reset();
                    OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
                    String fileName = file.getName();
                    response.setContentType("application/octet-stream");
                    String userAgent = request.getHeader("User-Agent");
                    fileName = getFileDownName(fileName, userAgent);
                    response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
                    toClient.write(buffer);
                    toClient.flush();
                    toClient.close();
                    var15 = false;
                    break label79;
                } catch (Exception var19) {
                    logger.error("发生了异常异常信息为：", var19);
                    var15 = false;
                } finally {
                    if (var15) {
                        try {
                            f = new File(file.getPath());
                            f.delete();
                        } catch (Exception var16) {
                            logger.error("发生了异常异常信息为：", var16);
                        }

                    }
                }

                try {
                    f = new File(file.getPath());
                    f.delete();
                } catch (Exception var17) {
                    logger.error("发生了异常异常信息为：", var17);
                }

                return response;
            }

            try {
                f = new File(file.getPath());
                f.delete();
            } catch (Exception var18) {
                logger.error("发生了异常异常信息为：", var18);
            }
        }

        return response;
    }

    public static void toZip(String srcDir, String tempPath, HttpServletRequest request, HttpServletResponse response, boolean KeepDirStructure) {
        File zipTmpFile = new File(tempPath);

        try {
            response.reset();
            FileOutputStream fous = new FileOutputStream(zipTmpFile);
            toZip(srcDir, fous, KeepDirStructure);
            fous.close();
            downloadZip(zipTmpFile, request, response);
        } catch (IOException var7) {
            logger.error("发生了异常异常信息为：", var7);
        }

    }

    public static void toZip(String srcDir, OutputStream out, boolean KeepDirStructure) throws RuntimeException {
        long start = System.currentTimeMillis();
        ZipOutputStream zos = null;

        try {
            zos = new ZipOutputStream(out);
            File sourceFile = new File(srcDir);
            compress(sourceFile, zos, sourceFile.getName(), KeepDirStructure);
            long end = System.currentTimeMillis();
            System.out.println("压缩完成，耗时：" + (end - start) + " ms");
        } catch (Exception var16) {
            throw new RuntimeException("zip error from ZipUtils", var16);
        } finally {
            if (zos != null) {
                try {
                    zos.close();
                } catch (IOException var15) {
                    logger.error("发生了异常异常信息为：", var15);
                }
            }

        }

    }

    public static void toZip(List<File> srcFiles, OutputStream out) throws RuntimeException {
        long start = System.currentTimeMillis();
        ZipOutputStream zos = null;

        try {
            zos = new ZipOutputStream(out);
            Iterator var5 = srcFiles.iterator();

            while(var5.hasNext()) {
                File srcFile = (File)var5.next();
                byte[] buf = new byte[2048];
                zos.putNextEntry(new ZipEntry(srcFile.getName()));
                FileInputStream in = new FileInputStream(srcFile);

                int len;
                while((len = in.read(buf)) != -1) {
                    zos.write(buf, 0, len);
                }

                zos.closeEntry();
                in.close();
            }

            long end = System.currentTimeMillis();
            System.out.println("压缩完成，耗时：" + (end - start) + " ms");
        } catch (Exception var17) {
            throw new RuntimeException("zip error from ZipUtils", var17);
        } finally {
            if (zos != null) {
                try {
                    zos.close();
                } catch (IOException var16) {
                    logger.error("发生了异常异常信息为：", var16);
                }
            }

        }
    }

    private static void compress(File sourceFile, ZipOutputStream zos, String name, boolean KeepDirStructure) throws Exception {
        byte[] buf = new byte[2048];
        if (sourceFile.isFile()) {
            zos.putNextEntry(new ZipEntry(name));
            FileInputStream in = new FileInputStream(sourceFile);

            int len;
            while((len = in.read(buf)) != -1) {
                zos.write(buf, 0, len);
            }

            zos.closeEntry();
            in.close();
        } else {
            File[] listFiles = sourceFile.listFiles();
            if (listFiles != null && listFiles.length != 0) {
                File[] var11 = listFiles;
                int var7 = listFiles.length;

                for(int var8 = 0; var8 < var7; ++var8) {
                    File file = var11[var8];
                    if (KeepDirStructure) {
                        compress(file, zos, name + "/" + file.getName(), KeepDirStructure);
                    } else {
                        compress(file, zos, file.getName(), KeepDirStructure);
                    }
                }
            } else if (KeepDirStructure) {
                zos.putNextEntry(new ZipEntry(name + "/"));
                zos.closeEntry();
            }
        }

    }

    public static boolean deleteDir(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();

            for(int i = 0; i < children.length; ++i) {
                boolean success = deleteDir(new File(dir, children[i]));
                if (!success) {
                    return false;
                }
            }
        }

        return dir.delete();
    }
}
